#include <iostream>
#include <ctime>
#include "block_queue.hpp"
#include "Task.hpp"
#include <unistd.h>

pthread_mutex_t gmutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t gc_cond = PTHREAD_COND_INITIALIZER;
pthread_cond_t gp_cond = PTHREAD_COND_INITIALIZER;
bool global = false; // 真表示满，假表示空
void *Consumer(void *args)
{
    BlockQueue<Task> *bq = static_cast<BlockQueue<Task> *>(args);
    for (int i = 0; i < 10; i++)
    {
        // int out = 0;
        Task t;
        sleep(1);
        bq->Pop(&t);

        t.Execute();
        // sleep(1);
        // pthread_mutex_lock(&gmutex); // 只把需要打印的代码锁起来就行了
        // std::cout << "consumer mutex" << std::endl;
        // while (global == false) // 空了，让producer
        // {
        //     std::cout << "consumer wait" << std::endl;
        //     pthread_cond_wait(&gc_cond, &gmutex);
        // }
        t.Result(); // 结果
        // global = false; // producer不等待 // consumer等待
        // std::cout << global << std::endl;
        // pthread_cond_signal(&gp_cond); // 唤醒gp_cond
        // pthread_mutex_unlock(&gmutex);

        // std::cout << "Consumer data:" << t.Result() << std::endl;
    }

    return nullptr;
}

void *Producer(void *args)
{
    BlockQueue<Task> *bq = static_cast<BlockQueue<Task> *>(args);

    for (int i = 0; i < 10; i++)
    {
        int in1 = rand() % 10 + 1; //[1, 10]
        int in2 = rand() % 10 + 1;
        Task t(in1, in2);
        // pthread_mutex_lock(&gmutex);
        // std::cout << "producer mutex" << std::endl;
        // while (global == true) // 满了，让consumer
        // {
        //     std::cout << "producer wait" << std::endl;
        //     pthread_cond_wait(&gp_cond, &gmutex);
        // }

        // global = true; // producer等待 // consumer不用等待
        // std::cout << global << std::endl;
        // pthread_cond_signal(&gc_cond); // 唤醒gc_cond
        // pthread_mutex_unlock(&gmutex);
        bq->Enqueue(&t);
        t.Debug(); // 问题

        // std::cout << "Producer data:" << in << std::endl;
    }

    return nullptr;
}

int main()
{
    srand(time(nullptr) ^ getpid());                // 产生随机数种子
    BlockQueue<Task> *bq = new BlockQueue<Task>(1); // 阻塞队列---共享内存

    pthread_t p_tid1, p_tid2; // 生产者
    pthread_create(&p_tid1, nullptr, Producer, (void *)bq);
    // pthread_create(&p_tid2, nullptr, Producer, (void *)bq);

    pthread_t c_tid1, c_tid2, c_tid3; // 消费者
    pthread_create(&c_tid1, nullptr, Consumer, (void *)bq);
    // pthread_create(&c_tid2, nullptr, Consumer, (void *)bq);sss
    //  pthread_create(&c_tid3, nullptr, Consumer, (void *)bq);

    pthread_join(p_tid1, nullptr);
    // pthread_join(p_tid2, nullptr);
    pthread_join(c_tid1, nullptr);
    // pthread_join(c_tid2, nullptr);
    // pthread_join(c_tid3, nullptr);

    delete bq;

    return 0;
}